package com.block.match.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.block.common.annotate.RedisLock;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.service.IChannelCommonService;
import com.block.common.service.IMerchantCommonService;
import com.block.common.service.LogFactory;
import com.block.common.vo.ResponseVo;
import com.block.db.entity.*;
import com.block.db.mapper.DataMatchOrderInfoMapper;
import com.block.db.mapper.DataMatchOrderItemMapper;
import com.block.match.constant.DataMatchConstant;
import com.block.match.enums.OrderStatusEnum;
import com.block.match.model.dto.MatchOrderResultDTO;
import com.block.match.model.vo.MatchOrderItem;
import com.block.match.model.vo.MatchResultVO;
import com.block.match.service.IDataMatchOrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.block.match.service.IDataMatchOrderItemService;
import com.block.merchant.model.result.DataMatchResult;
import com.block.merchant.model.result.MatchMerchantInfo;
import com.block.merchant.model.vo.MerchantAbiBDataPushInfoVO;
import com.block.merchant.service.IMerchantBaseInfoService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 商户匹配订单信息 服务实现类
 * </p>
 *
 * @author 
 * @since 2023-08-15
 */
@Service
public class DataMatchOrderInfoServiceImpl extends ServiceImpl<DataMatchOrderInfoMapper, DataMatchOrderInfo> implements IDataMatchOrderInfoService {

    private static final Logger log = LogFactory.getCommLog();

    @Autowired
    IDataMatchOrderItemService dataMatchOrderItemService;
    @Autowired
    NotifyExceptionService notifyExceptionService;
    @Autowired
    IMerchantBaseInfoService merchantBaseInfoService;
    @Resource
    DataMatchOrderItemMapper dataMatchOrderItemMapper;
    @Autowired
    IMerchantCommonService merchantCommonService;

    @Autowired
    IChannelCommonService channelCommonService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private static List<Long> uidList = Arrays.asList(1851561113350610946L);


    /**
     * 初始化匹配订单信息
     */
    @Override
    public DataMatchOrderInfo initMatchOrderInfo(MemberSourceInfo memberSourceInfo){
        DataMatchOrderInfo dataMatchOrderInfo = new DataMatchOrderInfo();
        dataMatchOrderInfo.setDateInfo(LocalDate.now().toString());
        dataMatchOrderInfo.setUid(memberSourceInfo.getUid());
        dataMatchOrderInfo.setAppCode(memberSourceInfo.getAppCode());
        dataMatchOrderInfo.setAppName(memberSourceInfo.getAppName());
        dataMatchOrderInfo.setChannelCode(memberSourceInfo.getChannelCode());
        dataMatchOrderInfo.setChannelName(memberSourceInfo.getChannelName());
        dataMatchOrderInfo.setStatus(OrderStatusEnum.INIT.getValue());
        // 平台协议地址
        boolean save = this.save(dataMatchOrderInfo);
        if (save){
            return this.getById(dataMatchOrderInfo.getId());
        }
        return null;
    }

    /**
     * 更新保存匹配结果
     *
     * @param dataMatchResult
     * @param memberSourceInfo
     */
    @Override
    public List<MatchOrderResultDTO> saveMatchOrderResult(DataMatchResult dataMatchResult, DataMatchOrderInfo dataMatchOrderInfo, MemberSourceInfo memberSourceInfo) {

        List<MatchOrderResultDTO> resultDTOList = new ArrayList<>();// 所有的结果
        List<MatchOrderResultDTO> pageResultDTOList = new ArrayList<>();// 授权页展示的结果

        List<MatchMerchantInfo> merchantInfoList = dataMatchResult.getMerchantInfoList();

        List<String> matchIdList = new ArrayList<>();
        List<String> pageIdList = new ArrayList<>();
        if (CollUtil.isNotEmpty(merchantInfoList)){
            for (MatchMerchantInfo matchMerchantInfo : merchantInfoList) {

                try {
                    // 生成
                    DataMatchOrderItem matchOrderItem =
                            dataMatchOrderItemService.initMatchOrderItem(matchMerchantInfo, dataMatchOrderInfo, memberSourceInfo);

                    if (ObjectUtil.isNotEmpty(matchOrderItem)){

                        MatchOrderResultDTO orderResultDTO = new MatchOrderResultDTO();
                        orderResultDTO.setOrderItemId(matchOrderItem.getId());
                        orderResultDTO.setMatchMerchantInfo(matchMerchantInfo);

                        // 所有匹配的结果
                        matchIdList.add(String.valueOf(matchMerchantInfo.getInfoId()));
                        resultDTOList.add(orderResultDTO);

                        pageResultDTOList.add(orderResultDTO);
                    }
                }catch (Exception exception){
                    exception.printStackTrace();
                    notifyExceptionService.notifyNoticeInfo("INIT_ORDER_ITEM", "初始化订单子项", JSON.toJSONString(dataMatchResult), exception);
                }
            }
        }

        // 更新匹配订单状态
        DataMatchOrderInfo updateEntity = new DataMatchOrderInfo();
        updateEntity.setId(dataMatchOrderInfo.getId());
        updateEntity.setStatus(OrderStatusEnum.WAIT_PUSH.getValue());
        updateEntity.setMatchIds(JSON.toJSONString(matchIdList));
        this.updateById(updateEntity);

        return pageResultDTOList;
    }

    /**
     * 授权推送订单
     * @param orderId 订单信息
     * @param itemOrderIds 子订单信息
     * @return
     */
    @Override
    @RedisLock(lockName = "SOURCE::MATCH::PUSH", key = "#orderId" )
    public ResponseVo approveToPush(Long uid, String orderId, String itemOrderIds, String approveImageUrl) {

        /**
         * todo 订单状态，订单信息的判断
         *  分布式锁
         */
        DataMatchOrderInfo matchOrderInfo = this.getById(orderId);
        if (ObjectUtil.isEmpty(matchOrderInfo)){
            return new ResponseVo(AppRspCodeConstant.PARAM_ERROR, "订单信息为空");
        }
        if (!ObjectUtil.equals(matchOrderInfo.getUid(), uid)){
            return new ResponseVo(AppRspCodeConstant.PARAM_ERROR, "非本人订单，不可操纵");
        }
//        LocalDateTime nowtime = LocalDateTime.now();
//        if (nowtime.isAfter(matchOrderInfo.getExpireTime())){
//            return new ResponseVo(AppRspCodeConstant.PARAM_ERROR, "匹配订单超时，不可操作");
//        }
//        if (!StrUtil.equals(OrderStatusEnum.WAIT_PUSH.getValue(), matchOrderInfo.getStatus())){
//            return new ResponseVo(AppRspCodeConstant.PARAM_ERROR, "订单状态错误，不可操作");
//        }

        // 测试账号直接返回推送成功
        if (uidList.contains(uid)){
            return new ResponseVo(AppRspCodeConstant.SUCCESS);
        }

        /**
         * 授权推送统计
         */
        CountInfoDTO countInfoDTO = new CountInfoDTO(matchOrderInfo.getChannelCode());
        countInfoDTO.setApprovePushNumber(1);


        DataMatchOrderInfo updateEntity = new DataMatchOrderInfo();
        updateEntity.setId(matchOrderInfo.getId());
        updateEntity.setStatus(OrderStatusEnum.PUSHING.getValue());
        updateEntity.setApproveIds(itemOrderIds);
        updateEntity.setApproveImageUrl(approveImageUrl);
        boolean updateOrder = this.updateById(updateEntity);
        log.info("【匹配订单授权推送】更新匹配订单【updateOrder】{}【orderId】{}", updateOrder, orderId);
//        if (!updateOrder){
//            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "订单更新失败");
//        }

        List<String> itemOrderIdList = JSON.parseArray(itemOrderIds, String.class);

        int size = itemOrderIdList.size();

        countInfoDTO.setPushCount(size);

        channelCommonService.updateChannelCount(countInfoDTO);

        List<String> pushSuccessIdList = new ArrayList<>();
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (String itemOrderId : itemOrderIdList) {
            try {
                // 订单项推送是否成功
                DataMatchOrderItem orderItem = dataMatchOrderItemService.toPushItemOrder(orderId, itemOrderId);
                if (ObjectUtil.isNotEmpty(orderItem)){
                    pushSuccessIdList.add(itemOrderId);
                    totalAmount = totalAmount.add(orderItem.getProfitAmount());
                }
            }catch (Exception exception){
                exception.printStackTrace();
                String content = StrUtil.format("【uid】{}【orderId】{}【orderItemId】{}", uid, orderId, itemOrderId);
                notifyExceptionService.notifyNoticeInfo("MERCHANT_APPROVE_PUSH", "商户匹配订单授权推送", content, exception);
            }
        }

        /**
         * 更新推送订单结果
         */
        DataMatchOrderInfo updateEntityFinal = new DataMatchOrderInfo();
        updateEntityFinal.setId(matchOrderInfo.getId());
        updateEntityFinal.setStatus(OrderStatusEnum.SUCCESS.getValue());
        updateEntityFinal.setSuccessIds(JSON.toJSONString(pushSuccessIdList));
        updateEntityFinal.setProfitAmount(totalAmount);
        boolean updateOrderFinal = this.updateById(updateEntityFinal);
        log.info("【匹配订单授权推送】更新匹配订单【updateOrder】{}【pushSuccessIdList】{}", updateOrderFinal, JSON.toJSONString(pushSuccessIdList));


        List<String> ids = JSON.parseArray(itemOrderIds, String.class);
        for (String itemOrderId : ids) {
            String redisKey = StrUtil.format(RedisKeyConstant.MERCHANT_PUSH_UID_ITEMID ,uid,itemOrderId);
            stringRedisTemplate.delete(redisKey);
        }
        return new ResponseVo(AppRspCodeConstant.SUCCESS);
    }


    @Override
    public boolean handleManualToPush(MemberSourceInfo memberSourceInfo, MerchantTaskInfo merchantTaskInfo, MatchMerchantInfo matchMerchantInfo) throws Exception {

        // 初始化订单信息
        DataMatchOrderInfo matchOrderInfo = this.initMatchOrderInfo(memberSourceInfo);

        // 初始化子订单项信息
        DataMatchOrderItem matchOrderItem = dataMatchOrderItemService.initMatchOrderItem(matchMerchantInfo, matchOrderInfo, memberSourceInfo);

        // 更新订单金额
        DataMatchOrderItem updateOrderItem = new DataMatchOrderItem();
        updateOrderItem.setId(matchOrderItem.getId());
        updateOrderItem.setProfitAmount(matchMerchantInfo.getProfitAmount());
        dataMatchOrderItemService.updateById(updateOrderItem);

        // 获取推送子订单信息结果
        DataMatchOrderItem pushResultOrderItem = dataMatchOrderItemService.toPushItemOrder(String.valueOf(matchOrderInfo.getId()), String.valueOf(matchOrderItem.getId()));

        DataMatchOrderInfo updateEntityFinal = new DataMatchOrderInfo();
        updateEntityFinal.setId(matchOrderInfo.getId());
        updateEntityFinal.setStatus(OrderStatusEnum.SUCCESS.getValue());
        updateEntityFinal.setSuccessIds(JSON.toJSONString(matchOrderItem.getId()));
        updateEntityFinal.setProfitAmount(matchMerchantInfo.getProfitAmount());
        boolean updateOrderFinal = this.updateById(updateEntityFinal);

        return updateOrderFinal;
    }

    @Override
    public MerchantAbiBDataPushInfoVO manualApiBPush(MemberSourceInfo memberSourceInfo, MerchantTaskInfo merchantTaskInfo, MatchMerchantInfo matchMerchantInfo) throws Exception {
        // 初始化订单信息
        DataMatchOrderInfo matchOrderInfo = this.initMatchOrderInfo(memberSourceInfo);

        // 初始化子订单项信息
        DataMatchOrderItem matchOrderItem = dataMatchOrderItemService.initMatchOrderItem(matchMerchantInfo, matchOrderInfo, memberSourceInfo);


        MerchantAbiBDataPushInfoVO merchantAbiBDataPushInfoVO = new MerchantAbiBDataPushInfoVO();
        merchantAbiBDataPushInfoVO.setApproveUrl(matchMerchantInfo.getApproveUrl());
        merchantAbiBDataPushInfoVO.setInfoId(String.valueOf(matchMerchantInfo.getInfoId()));
        merchantAbiBDataPushInfoVO.setCompanyName(matchMerchantInfo.getCompanyName());
        merchantAbiBDataPushInfoVO.setCompanyLogo(matchMerchantInfo.getCompanyLogo());
        merchantAbiBDataPushInfoVO.setMaxLoanAmount(matchMerchantInfo.getMaxLoanAmount());
        merchantAbiBDataPushInfoVO.setMaxRate(matchMerchantInfo.getMaxRate());
        merchantAbiBDataPushInfoVO.setMinRate(matchMerchantInfo.getMinRate());
        merchantAbiBDataPushInfoVO.setStatus(false);

        // 更新订单金额
        DataMatchOrderItem updateOrderItem = new DataMatchOrderItem();
        updateOrderItem.setId(matchOrderItem.getId());
        updateOrderItem.setProfitAmount(matchMerchantInfo.getProfitAmount());
        dataMatchOrderItemService.updateById(updateOrderItem);

        // 获取推送子订单信息结果
        DataMatchOrderItem pushResultOrderItem = dataMatchOrderItemService.pushApiB(String.valueOf(matchOrderInfo.getId()), String.valueOf(matchOrderItem.getId()));
        merchantAbiBDataPushInfoVO.setApproveUrl(pushResultOrderItem.getApproveUrl());

        DataMatchOrderInfo updateEntityFinal = new DataMatchOrderInfo();
        updateEntityFinal.setId(matchOrderInfo.getId());
        updateEntityFinal.setStatus(OrderStatusEnum.SUCCESS.getValue());
        updateEntityFinal.setSuccessIds(JSON.toJSONString(matchOrderItem.getId()));
        updateEntityFinal.setProfitAmount(matchMerchantInfo.getProfitAmount());
        boolean updateOrderFinal = this.updateById(updateEntityFinal);

        if (updateOrderFinal){
            merchantAbiBDataPushInfoVO.setStatus(true);
        }

        return merchantAbiBDataPushInfoVO;
    }

    /**
     * 获取待授权列表信息
     * @param uid
     * @param orderNo
     * @return
     */
    @Override
    public ResponseVo getWaitApproveList(Long uid, String orderNo) {

        DataMatchOrderInfo matchOrderInfo = this.baseMapper.selectById(orderNo);
        if (ObjectUtil.isEmpty(matchOrderInfo)){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL);
        }

        MatchResultVO matchResultVO = new MatchResultVO();
        matchResultVO.setOrderId(String.valueOf(matchOrderInfo.getId()));
        if(StrUtil.equals(matchOrderInfo.getAppCode(),"anyirong_mini") || StrUtil.equals(matchOrderInfo.getAppCode(),"anyirongh5")){
            matchResultVO.setOrderProtocolUrl(StrUtil.format(DataMatchConstant.PAGE_APPROVE_URI, matchOrderInfo.getId()));
        }
        if(StrUtil.equals(matchOrderInfo.getAppCode(),"hongchang_mini")) {
            matchResultVO.setOrderProtocolUrl(StrUtil.format(DataMatchConstant.PAGE_APPROVE_URI_HONG, matchOrderInfo.getId()));
        }
        if(StrUtil.equals(matchOrderInfo.getAppCode(),"hengxiaorong_mini")) {
            matchResultVO.setOrderProtocolUrl(StrUtil.format(DataMatchConstant.PAGE_APPROVE_URI_RONG, matchOrderInfo.getId()));
        }

        List<DataMatchOrderItem> orderItemList = dataMatchOrderItemMapper.getEntityListByOrderNoExt(orderNo);
        if (CollUtil.isEmpty(orderItemList)){
            matchResultVO.setMatchSuccess(false);
            return new ResponseVo(AppRspCodeConstant.SUCCESS, matchResultVO);
        }

        List<MatchOrderItem> resultItemList = new ArrayList<>();
        for (DataMatchOrderItem matchOrderItem : orderItemList) {
            MatchOrderItem  orderItem = new MatchOrderItem();

            orderItem.setOrderItemId(String.valueOf(matchOrderItem.getId()));

            orderItem.setInfoType(matchOrderItem.getInfoType());
            orderItem.setApproveFlag(matchOrderItem.getApproveFlag());
            orderItem.setApproveUrl(matchOrderItem.getApproveUrl());
            orderItem.setProtocolUrl(matchOrderItem.getProtocolUrl());

            // 查询机构信息
            MerchantBaseInfo merchantBaseInfo = merchantCommonService.getMerchantBaseInfo(matchOrderItem.getInfoId());
            orderItem.setCompanyName(merchantBaseInfo.getCompanyName());
            orderItem.setCompanyShortName(merchantBaseInfo.getCompanyShortName());
            orderItem.setCompanyTitle(merchantBaseInfo.getCompanyTitle());
            orderItem.setCompanySubTitle(merchantBaseInfo.getCompanySubTitle());

            orderItem.setCompanyLogo(merchantBaseInfo.getCompanyLogo());
            orderItem.setMaxLoanAmount(merchantBaseInfo.getMaxLoanAmount());
            orderItem.setMaxRate(merchantBaseInfo.getMaxRate());
            orderItem.setMinRate(merchantBaseInfo.getMinRate());

            resultItemList.add(orderItem);
        }
        matchResultVO.setMatchSuccess(true);
        matchResultVO.setOrderItemList(resultItemList);

        return new ResponseVo(AppRspCodeConstant.SUCCESS, matchResultVO);
    }

    @Override
    public ResponseVo approveClickCount(String orderNo, String orderItemId) {

        DataMatchOrderItem updateEntity = new DataMatchOrderItem();
        updateEntity.setId(Long.valueOf(orderItemId));
        updateEntity.setClickPushFlag(1);
        updateEntity.setStatus(OrderStatusEnum.WAIT_CONFIRM.getValue());
        updateEntity.setRemarkInfo("PRODUCT_LIST");
        dataMatchOrderItemMapper.updateById(updateEntity);

        return new ResponseVo(AppRspCodeConstant.SUCCESS);
    }



}
